Continuing to work through regex, and updated libcxx_by_chapter.pdf with weekly test results git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@106790 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/regex b/include/regex index e48f072..0277774 100644 --- a/include/regex +++ b/include/regex 
@@ -720,6 +720,7 @@  #include <__config>  #include <stdexcept>  #include <__locale> +#include <initializer_list>    #pragma GCC system_header   @@ -895,7 +896,8 @@  error_space,  error_badrepeat,  error_complexity, - error_stack + error_stack, + error_temp  };    } // regex_constants @@ -1193,7 +1195,7 @@  {  __ch |= 0x20; // tolower  if ('a' <= __ch && __ch <= 'f') - return __ch - 'a' + 10; + return __ch - ('a' - 10);  }  }  return -1; @@ -1207,6 +1209,510 @@  return __value(static_cast<unsigned char>(__ct_->narrow(__ch, char_type())), __radix);  }   +template <class _CharT, class _Traits = regex_traits<_CharT> > +class basic_regex +{ +public: + // types: + typedef _CharT value_type; + typedef regex_constants::syntax_option_type flag_type; + typedef typename _Traits::locale_type locale_type; + +private: + _Traits __traits_; + flag_type __flags_; + unsigned __marked_count_; + +public: + // constants: + static const/*expr*/ regex_constants::syntax_option_type icase = regex_constants::icase; + static const/*expr*/ regex_constants::syntax_option_type nosubs = regex_constants::nosubs; + static const/*expr*/ regex_constants::syntax_option_type optimize = regex_constants::optimize; + static const/*expr*/ regex_constants::syntax_option_type collate = regex_constants::collate; + static const/*expr*/ regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript; + static const/*expr*/ regex_constants::syntax_option_type basic = regex_constants::basic; + static const/*expr*/ regex_constants::syntax_option_type extended = regex_constants::extended; + static const/*expr*/ regex_constants::syntax_option_type awk = regex_constants::awk; + static const/*expr*/ regex_constants::syntax_option_type grep = regex_constants::grep; + static const/*expr*/ regex_constants::syntax_option_type egrep = regex_constants::egrep; + + // construct/copy/destroy: + basic_regex(); + explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript) + : __flags_(__f), __marked_count_(0) + {__parse(__p, __p + __traits_.length(__p));} + basic_regex(const value_type* __p, size_t __len, flag_type __f) + : __flags_(__f), __marked_count_(0) + {__parse(__p, __p + __len);} + basic_regex(const basic_regex&); +#ifdef _LIBCPP_MOVE + basic_regex(basic_regex&&); +#endif + template <class _ST, class _SA> + explicit basic_regex(const basic_string<value_type, _ST, _SA>& __p, + flag_type __f = regex_constants::ECMAScript) + : __flags_(__f), __marked_count_(0) + {__parse(__p.begin(), __p.end());} + template <class _ForwardIterator> + basic_regex(_ForwardIterator __first, _ForwardIterator __last, + flag_type __f = regex_constants::ECMAScript) + : __flags_(__f), __marked_count_(0) + {__parse(__first, __last);} + basic_regex(initializer_list<value_type> __il, + flag_type __f = regex_constants::ECMAScript) + : __flags_(__f), __marked_count_(0) + {__parse(__il.begin(), __il.end());} + + ~basic_regex(); + + basic_regex& operator=(const basic_regex&); +#ifdef _LIBCPP_MOVE + basic_regex& operator=(basic_regex&&); +#endif + basic_regex& operator=(const value_type* __p); + basic_regex& operator=(initializer_list<value_type> __il); + template <class _ST, class _SA> + basic_regex& operator=(const basic_string<value_type, _ST, _SA>& __p); + + // assign: + basic_regex& assign(const basic_regex& __that); +#ifdef _LIBCPP_MOVE + basic_regex& assign(basic_regex&& __that); +#endif + basic_regex& assign(const value_type* __p, flag_type __f = regex_constants::ECMAScript); + basic_regex& assign(const value_type* __p, size_t __len, flag_type __f); + template <class _ST, class _SA> + basic_regex& assign(const basic_string<value_type, _ST, _SA>& __s, + flag_type __f = regex_constants::ECMAScript); + template <class _InputIterator> + basic_regex& assign(_InputIterator __first, _InputIterator __last, + flag_type __f = regex_constants::ECMAScript); + basic_regex& assign(initializer_list<value_type> __il, + flag_type = regex_constants::ECMAScript); + + // const operations: + unsigned mark_count() const {return __marked_count_;} + flag_type flags() const {return __flags_;} + + // locale: + locale_type imbue(locale_type __loc) {return __traits_.imbue(__loc);} + locale_type getloc() const {return __traits_.getloc();} + + // swap: + void swap(basic_regex&); + +private: + template <class _ForwardIterator> + void __parse(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_RE_expression(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_simple_RE(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_nondupl_RE(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_one_char_or_coll_elem_RE(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_Back_open_paren(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_Back_close_paren(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_Back_open_brace(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_Back_close_brace(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_BACKREF(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_ORD_CHAR(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last); + template <class _ForwardIterator> + _ForwardIterator + __parse_RE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last); + + void __push_l_anchor(); + void __push_r_anchor(); + void __push_match_any(); + void __push_greedy_inf_repeat(int __min); + void __push_exact_repeat(int __count); + void __push_repeat(int __min, int __max); +}; + +template <class _CharT, class _Traits> +inline +basic_regex<_CharT, _Traits>::basic_regex() + : __traits_(), __flags_(), __marked_count_(0) +{ +} + +template <class _CharT, class _Traits> +basic_regex<_CharT, _Traits>::~basic_regex() +{ +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +void +basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first, + _ForwardIterator __last) +{ + switch (__flags_ & 0x3F0) + { + case ECMAScript: + break; + case basic: + __parse_basic_reg_exp(__first, __last); + break; + case extended: + break; + case awk: + break; + case grep: + break; + case egrep: + break; + default: + throw regex_error(regex_constants::error_temp); + } +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_basic_reg_exp(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + if (*__first == '^') + { + __push_l_anchor(); + ++__first; + } + if (__first != __last) + { + __first = __parse_RE_expression(__first, __last); + if (__first != __last) + { + _ForwardIterator __temp = next(__first); + if (__temp == __last && *__first == '$') + { + __push_r_anchor(); + ++__first; + } + } + } + if (__first != __last) + throw regex_error(regex_constants::error_temp); + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_RE_expression(_ForwardIterator __first, + _ForwardIterator __last) +{ + while (true) + { + _ForwardIterator __temp = __parse_simple_RE(__first, __last); + if (__temp == __first) + break; + __first = __temp; + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_simple_RE(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = __parse_nondupl_RE(__first, __last); + if (__temp != __first) + { + __first = __temp; + __first = __parse_RE_dupl_symbol(__first, __last); + } + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_nondupl_RE(_ForwardIterator __first, + _ForwardIterator __last) +{ + _ForwardIterator __temp = __first; + __first = __parse_one_char_or_coll_elem_RE(__first, __last); + if (__temp == __first) + { + __temp = __parse_Back_open_paren(__first, __last); + if (__temp != __first) + { + __first = __parse_RE_expression(__temp, __last); + __temp = __parse_Back_close_paren(__first, __last); + if (__temp == __first) + throw regex_error(regex_constants::error_paren); + __first = __temp; + ++__marked_count_; + } + else + __first = __parse_BACKREF(__first, __last); + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_RE( + _ForwardIterator __first, + _ForwardIterator __last) +{ + _ForwardIterator __temp = __first; + __first = __parse_ORD_CHAR(__first, __last); + if (__temp == __first) + { + __first = __parse_QUOTED_CHAR(__first, __last); + if (__temp == __first) + { + if (__first != __last && *__first == '.') + { + __push_match_any(); + ++__first; + } + else + __first = __parse_bracket_expression(__first, __last); + } + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_Back_open_paren(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = next(__first); + if (__temp != __last) + { + if (*__first == '\\' && *__temp == '(') + __first = ++__temp; + } + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_Back_close_paren(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = next(__first); + if (__temp != __last) + { + if (*__first == '\\' && *__temp == ')') + __first = ++__temp; + } + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_Back_open_brace(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = next(__first); + if (__temp != __last) + { + if (*__first == '\\' && *__temp == '{') + __first = ++__temp; + } + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_Back_close_brace(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = next(__first); + if (__temp != __last) + { + if (*__first == '\\' && *__temp == '}') + __first = ++__temp; + } + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = next(__first); + if (__temp != __last) + { + if (*__first == '\\' && '1' <= *__temp && *__temp <= '9') + { + __push_back_ref(*__temp - '0'); + __first = ++__temp; + } + } + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_ORD_CHAR(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = next(__first); + if (__temp == __last && *__first == '$') + return __first; + // Not called inside a bracket + if (*__first == '.' || *__first == '\\' || *__first == '[') + return __first; + __push_ord_char(*__first); + ++__first; + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = next(__first); + if (__temp != __last) + { + if (*__first == '\\') + { + switch (*__temp) + { + case '^': + case '.': + case '*': + case '[': + case '$': + case '\\': + __push_ord_char(*__temp); + __first = ++__temp; + break; + } + } + } + } + return __first; +} + +template <class _CharT, class _Traits> +template <class _ForwardIterator> +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + if (__first == '*') + { + __push_greedy_inf_repeat(0); + ++__first; + } + else + { + _ForwardIterator __temp = __parse_Back_open_brace(__first, __last); + if (__temp != __first) + { + int __min = 0; + __first = __temp; + __temp = __parse_DUP_COUNT(__first, __last, __min); + if (__temp == __first) + throw regex_error(regex_constants::error_badbrace); + __first = __temp; + if (__first == __last) + throw regex_error(regex_constants::error_brace); + if (*__first != ',') + { + __temp = __parse_Back_close_brace(__first, __last); + if (__temp == __first) + throw regex_error(regex_constants::error_brace); + __push_exact_repeat(__min); + __first = __temp; + } + else + { + ++__first; // consume ',' + int __max = -1; + __first = __parse_DUP_COUNT(__first, __last, __max); + __temp = __parse_Back_close_brace(__first, __last); + if (__temp == __first) + throw regex_error(regex_constants::error_brace); + if (__max == -1) + __push_greedy_inf_repeat(__min); + else + { + if (__max < __min) + throw regex_error(regex_constants::error_badbrace); + __push_repeat(__min, __max); + } + __first = __temp; + } + } + } + } + return __first; +} + +typedef basic_regex<char> regex; +typedef basic_regex<wchar_t> wregex; +  _LIBCPP_END_NAMESPACE_STD    #endif // _LIBCPP_REGEX